package littlewhisker.utils {
	import caurina.transitions.Tweener;

	import flash.geom.Point;
	import flash.display.Sprite;

	import littlewhisker.application.mvc.Controller;

	/**
	 * @author Philip
	 */
	public class Mask extends Controller {
		
		public static var UP:String = "up";
		public static var DOWN:String = "down";
		public static var LEFT:String = "left";
		public static var RIGHT:String = "right";
		
		private static const DEFAULT_TRANSITION_TIME:Number = 0.4;
		private static const DEFAULT_TRANSITION_TYPE:String = "easeOutQuint";
		private static const DEFAULT_DIRECTION:String = "LEFT";
		
		private var _target:Sprite;
		private var _mask:Sprite;
		private var _settings:Object;
		
		private var _transitionType:String;
		private var _transituinTime: Number;
		private var maskHolder : Sprite;
		private var _direction : String;

		/**
		 * @param revealed : Boolean
		 * if true, the target will start off visible and inteds to hide during the tween
		 * if true, the target will start off invisible and inteds to reveal during the tween
		 * 
		 * @param view : Sprite
		 * the displayobject where your target is positioned
		 * 
		 * @param target : Sprite
		 * the display object you want to mask
		 * 
		 * @param settings : Object (optional)
		 * direction: String - use the constants whitin this class UP, DOWN, LEFT, RIGHT.
		 * time: transition time in seconds
		 * startX: x location of where the mask starts
		 * startY: y location of where the mask starts
	 	 * destinationX: x location where the mask will tween to
		 * destinationY: y location where the mask will tween to
		 */
		 
		public function get transitionType() : String {
			return _transitionType;
		}
		
		public function set transitionType(transitionType : String) : void {
			_transitionType = transitionType;
		}
		
		public function get transituinTime() : Number {
			return _transituinTime;
		}
		
		public function set transituinTime(transituinTime : Number) : void {
			_transituinTime = transituinTime;
		}
		
		public function setSize(width:Number, height:Number):void{
			mask.width = width;
			mask.height = height+5;
		}
		
		public function get direction() : String {
			return _direction;
		}
		
		public function set direction(direction : String) : void {
			_direction = direction;
		}
		 
		public function get target() : Sprite {
			return _target;
		}
		
		public function set target(target : Sprite) : void {
			_target = target;
		}
		
		public function get mask() : Sprite {
			return _mask;
		}
		
		public function set mask(mask : Sprite) : void {
			_mask = mask;
		}
		
		public function get settings() : Object {
			return _settings;
		}
		
		public function set settings(settings : Object) : void {
			_settings = settings;
		}
		
		public function Mask(view:Sprite, target:Sprite, revealed:Boolean, time:Number = .4, type:String = "easeOutQuint"):void{
			this.view = view;
			this.target = target;
			this.transitionType = type;
			this.transituinTime = time;
			addMask();
			if(!revealed) mask.y = -target.height;
		}
		
		private function addMask():void{
			maskHolder = new Sprite();
			view.addChild(maskHolder);
			mask = new Sprite();
			maskHolder.addChild(mask);
			mask.graphics.beginFill(0x00aa00);
			mask.graphics.drawRect(0, 0, target.width, target.height+5);
			target.mask = mask;
		}
		
		public function hide(direction:String = null, transition:String = null, time:Number = DEFAULT_TRANSITION_TIME, settings:Object = null):void{
			this.direction = direction;
			execute("hide",transition,time,settings);
		}
		 
			
		public function show(direction:String = null, transition:String = null, time:Number = DEFAULT_TRANSITION_TIME, settings:Object = null):void{
			this.direction = direction;
			execute("show",transition,time,settings);
		}
		
		private function execute(operation:String, transition:String = null, time:Number = DEFAULT_TRANSITION_TIME, settings:Object = null):void{
			var startX:Number = mask.x;
			var startY:Number = mask.y;
			
			var destinationX:Number = 0;
			var destinationY:Number = 0;
			
			var direction:String;
			settings.direction ? direction = settings.direction : direction = this.direction;
			
			var point:Point = getPosition(direction);
			
			if(operation == "hide"){
				destinationX = point.x;
				destinationY = point.y;
			} else {
				//startX = point.x;
				//startY = point.y;
			}
			
			if(settings.startX)  startX = settings.startX;
			if(settings.startY)  startY = settings.startY;
					
			if(settings.destinationX) destinationX = settings.destinationX;
			if(settings.destinationY) destinationY = settings.destinationY;
			
			var time:Number;
			settings.time ? time = settings.time : time = DEFAULT_TRANSITION_TIME;
			
			var type:String;
			settings.type ? type = settings.type : type = DEFAULT_TRANSITION_TYPE;
			
			var maskHolder:Sprite = new Sprite();
			maskHolder.x = target.x;
			maskHolder.y = target.y;
			
			view.addChild(maskHolder);
			
			
			
			mask.x = startX;
			mask.y = startY;
							
			var tempOnUpdate:Function = function():void{
				maskHolder.x = target.x;
				maskHolder.y = target.y;
			}
			
			var tempOnComplete:Function = function():void{
				
				//if(settings.event) dispatchEvent(settings.event as Event);
				if(settings.callback) {
					var arg:Array;
					settings.arguments ? arg = settings.arguments : arg = new Array();
					settings.callback.apply(arg);
				}
			}
					
			Tweener.addTween(mask,{time:time,x:destinationX, y:destinationY, transition:type, onComplete:tempOnComplete, onUpdate:tempOnUpdate});
		}
		
		private function getPosition(direction:String):Point{
			var point:Point = new Point();
			switch (direction){
				case UP:
					point.x = target.x;
					point.y = -target.height-5;
					break;
				case DOWN:
					point.x = target.x;
					point.y = -target.height-5;
					break;
				case LEFT:
					point.x = -target.width;
					point.y = target.y;
					break;
				case RIGHT:
					point.x = target.width;
					point.y = target.y;
					break;
			}
			return point;
		}
		
		
	}
}
